/*
   Copyright 2008, Andres Postiglioni

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package com.aconcagua.factory {
  import com.aconcagua.beans.BeanDefinition;
  import com.aconcagua.beans.BeanDefinitionException;
  import com.aconcagua.beans.BeanDefinitionSupport;
  import com.aconcagua.beans.ConstructorArg;
  import com.aconcagua.beans.Property;
  import com.aconcagua.beans.Ref;
  import com.aconcagua.beans.Value;
  import com.aconcagua.dummy.DummyBean;
  import com.aconcagua.dummy.DummyBeanFactory;
  import com.aconcagua.dummy.DummyFactoryAwareBean;

  import flexunit.framework.TestCase;

  /**
   * @author Andres Postiglioni
   */
  public class AbstractBeanFactoryTest extends TestCase {
    private var _beanFactory: AbstractBeanFactory;

    override public function setUp(): void {
      _beanFactory = new AbstractBeanFactory();
    }

    override public function tearDown():void {
      _beanFactory = null;
    }

    public function testRegisterBeanDefinitionWithNoType(): void {
      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(null);
      bean.name = "testBean"
      try {
        _beanFactory.registerBeanDefinition(bean);
        fail("Expected exception not thrown: BeanException");
      }
      catch(e: BeanDefinitionException) {
        //success!
      }
    }

    public function testRegisterSingletonDefinition(): void {
      const expectedType: Class = DummyBean;

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.scope = BeanDefinitionSupport.SCOPE_SINGLETON;
      bean.name = "dummyBean";

      _beanFactory.registerBeanDefinition(bean);
      this.assertGetSingletonBean(bean, expectedType);
    }

    public function testRegisterPrototypeDefinition(): void {
      const expectedType: Class = DummyBean;

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.scope = BeanDefinitionSupport.SCOPE_PROTOTYPE;
      bean.name = "dummyBean";

      _beanFactory.registerBeanDefinition(bean);

      this.assertGetPrototypeBean(bean, expectedType);
    }

    public function testAnonymousBean(): void {
      var anonymous: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "dummyBean";
      bean.addConstructorArg(new ConstructorArg(new Ref(anonymous)));

      _beanFactory.registerBeanDefinition(bean);
      assertNotNull(
        "Anonymous bean not injected",
        DummyBean(
          _beanFactory.getBean(bean.name)
        ).constructorBean
      );
    }
/*
    public function testDefaults(): void {
      fail("Test default is singleton, not-lazy, etc. etc.");
    }
 */
    /**
    * Test references to beans that have not been registered yet.
    **/
     public function testNotRegisteredReferences(): void {
      var constructorBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      constructorBean.name = "constructorBean";

      var propertyBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      propertyBean.name = "propertyBean";

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "dummyBean";
      bean.addConstructorArg(new ConstructorArg(new Ref(constructorBean)));
      bean.addProperty(new Property("propertyBean", new Ref(propertyBean)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);
      var constructorDummy: DummyBean = _beanFactory.getBean(constructorBean.name) as DummyBean;
      var propertyDummy: DummyBean = _beanFactory.getBean(propertyBean.name) as DummyBean;

      this.assertConstructorDependency(constructorDummy, dummyBean);
      this.assertPropertyDependency(propertyDummy, dummyBean);
    }

    public function testRegisteredReferences(): void {
      var constructorBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      constructorBean.name = "constructorBean";
      _beanFactory.registerBeanDefinition(constructorBean);

      var propertyBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      propertyBean.name = "propertyBean";
      _beanFactory.registerBeanDefinition(propertyBean);

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "dummyBean";
      bean.addConstructorArg(new ConstructorArg(new Ref(constructorBean)));
      bean.addProperty(new Property("propertyBean", new Ref(propertyBean)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);
      var constructorDummy: DummyBean = _beanFactory.getBean(constructorBean.name) as DummyBean;
      var propertyDummy: DummyBean = _beanFactory.getBean(propertyBean.name) as DummyBean;

      this.assertConstructorDependency(constructorDummy, dummyBean);
      this.assertPropertyDependency(propertyDummy, dummyBean);
    }

    public function testConstructorArgReference(): void {
      var referencedBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      referencedBean.name = "referencedBean";
      _beanFactory.registerBeanDefinition(referencedBean);

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "constructorBean";
      bean.addConstructorArg(new ConstructorArg(new Ref(referencedBean)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);

      var referencedDummy: DummyBean = _beanFactory.getBean(referencedBean.name) as DummyBean;
      this.assertConstructorDependency(referencedDummy, dummyBean);
    }

    public function testConstructorArgValue(): void {
      var dummyValue: DummyBean = new DummyBean();

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "constructorBean";
      bean.addConstructorArg(new ConstructorArg(new Value(dummyValue)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);

      this.assertConstructorDependency(dummyValue, dummyBean);
    }

    public function testSetPropertyReference(): void {
      var referencedBean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      referencedBean.name = "referencedBean";
      _beanFactory.registerBeanDefinition(referencedBean);

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "propertyBean";
      bean.addProperty(new Property("propertyBean", new Ref(referencedBean)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);
      var referencedDummy: DummyBean = _beanFactory.getBean(referencedBean.name) as DummyBean;

      this.assertPropertyDependency(referencedDummy, dummyBean);
    }

    public function testSetPropertyValue(): void {
      var dummyValue: DummyBean = new DummyBean();

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "propertyBean";
      bean.addProperty(new Property("propertyBean", new Value(dummyValue)));
      _beanFactory.registerBeanDefinition(bean);

      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);

      this.assertPropertyDependency(dummyValue, dummyBean);
    }

    public function testRegisterExistingBean(): void {
      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "propertyBean";
      _beanFactory.registerBeanDefinition(bean);
      try {
        _beanFactory.registerBeanDefinition(bean);
        fail("BeanDefinitionException was expected");
      }
      catch(e: BeanDefinitionException) {
        //success
      }
    }

     public function testPropertyPropertyCrossReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      beanA.addProperty(new Property("propertyBean", new Ref(beanB)));
      beanB.addProperty(new Property("propertyBean", new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanA);

      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(aDummy, bDummy);
      this.assertPropertyDependency(bDummy, aDummy);
    }


    /**
    * The constructor bean is registered before the property bean
    **/
     public function testConstructorPropertyCrossReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addProperty(new Property("propertyBean", new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanA);

      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(aDummy, bDummy);
      this.assertConstructorDependency(bDummy, aDummy);
    }

    /**
    * The constructor bean is registered before the property bean
    **/
     public function testIndirectConstructorPropertyCrossReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      var beanC: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanC.name = "beanC";

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanC)));
      beanC.addProperty(new Property("propertyBean", new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanA);

      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;
      var cDummy: DummyBean = _beanFactory.getBean(beanC.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(aDummy, cDummy);
      this.assertConstructorDependency(bDummy, aDummy);
      this.assertConstructorDependency(cDummy, bDummy);
    }

    /**
    * The constructor bean is registered before the property bean
    **/
     public function testComplexIndirectConstructorPropertyCrossReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      var beanC: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanC.name = "beanC";

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanC)));
      beanC.addProperty(new Property("propertyBean", new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanB);

      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;
      var cDummy: DummyBean = _beanFactory.getBean(beanC.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(aDummy, cDummy);
      this.assertConstructorDependency(bDummy, aDummy);
      this.assertConstructorDependency(cDummy, bDummy);
    }

    /**
    * The constructor bean is registered before the property bean. Lazy beans.
    **/
     public function testComplexIndirectConstructorPropertyCrossReferenceLazy(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";
      beanA.lazy = true;

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";
      beanB.lazy = true;

      var beanC: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanC.name = "beanC";
      beanC.lazy = true;

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanC)));
      beanC.addProperty(new Property("propertyBean", new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanB);

      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;
      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var cDummy: DummyBean = _beanFactory.getBean(beanC.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(aDummy, cDummy);
      this.assertConstructorDependency(bDummy, aDummy);
      this.assertConstructorDependency(cDummy, bDummy);
    }

    public function testPropertyConstructorCrossReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      beanA.addProperty(new Property("propertyBean", new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanA)));

      _beanFactory.registerBeanDefinition(beanA);

      var aDummy: DummyBean = _beanFactory.getBean(beanA.name) as DummyBean;
      var bDummy: DummyBean = _beanFactory.getBean(beanB.name) as DummyBean;

      //Asserts
      this.assertPropertyDependency(bDummy, aDummy);
      this.assertConstructorDependency(aDummy, bDummy);
    }

    public function testCircularReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanA)));

      try {
        _beanFactory.registerBeanDefinition(beanA);
        fail("BeanCreationException was expected");
      }
      catch(e: BeanCreationException) {
        //success
      }
    }

    public function testIndirectCircularReference(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";

      var beanC: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanC.name = "beanC";

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanC)));
      beanC.addConstructorArg(new ConstructorArg(new Ref(beanA)));

      try {
        _beanFactory.registerBeanDefinition(beanA);
        fail("BeanCreationException was expected");
      }
      catch(e: BeanCreationException) {
        //success
      }
    }

    public function testCircularReferencePrototypes(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";
      beanA.scope = BeanDefinitionSupport.SCOPE_PROTOTYPE;

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";
      beanB.scope = BeanDefinitionSupport.SCOPE_PROTOTYPE;

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanA)));

      try {
        _beanFactory.registerBeanDefinition(beanA);
        _beanFactory.registerBeanDefinition(beanB);

        _beanFactory.getBean(beanA.name);
        fail("BeanCreationException was expected");
      }
      catch(e: BeanCreationException) {
        //success
      }
    }


    public function testCircularReferencePrototypesUnregistered(): void {
      var beanA: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanA.name = "beanA";
      beanA.scope = BeanDefinitionSupport.SCOPE_PROTOTYPE;

      var beanB: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      beanB.name = "beanB";
      beanB.scope = BeanDefinitionSupport.SCOPE_PROTOTYPE;

      beanA.addConstructorArg(new ConstructorArg(new Ref(beanB)));
      beanB.addConstructorArg(new ConstructorArg(new Ref(beanA)));

      try {
        _beanFactory.registerBeanDefinition(beanA);

        _beanFactory.getBean(beanA.name);
        fail("BeanCreationException was expected");
      }
      catch(e: BeanCreationException) {
        //success
      }
    }

    public function testEagerBean(): void {
      var dummyValue: DummyBean = new DummyBean();

      var bean: MockBean = new MockBean(DummyBean);
      bean.name = "dummyBean";
      bean.lazy = false;
      _beanFactory.registerBeanDefinition(bean);

      assertTrue("Lazy bean has not been instantiated", bean.isInstantiated);
      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);
    }

    public function testLazyBean(): void {
      var dummyValue: DummyBean = new DummyBean();

      var bean: MockBean = new MockBean(DummyBean);
      bean.name = "dummyBean";
      bean.lazy = true;
      _beanFactory.registerBeanDefinition(bean);

      assertFalse("Lazy bean has been instantiated eagerly", bean.isInstantiated);
      var dummyBean: DummyBean = _beanFactory.getBean(bean.name);
      assertTrue("Lazy bean has not been instantiated", bean.isInstantiated);
    }

    public function testAlias(): void {
      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBean);
      bean.name = "dummyBean";

      _beanFactory.registerAlias("alias1", bean);
      _beanFactory.registerBeanDefinition(bean);
      _beanFactory.registerAlias("alias2", bean);

      var aliases: Array = _beanFactory.getAliases(bean.name);
      assertEquals("Two aliases were expected", 2, aliases.length);
      assertTrue("alias1 not found", aliases[0] == "alias1" || aliases[1] == "alias1");
      assertTrue("alias2 not found", aliases[0] == "alias2" || aliases[1] == "alias2");

      var alias1Bean: DummyBean = _beanFactory.getBean("alias1");
      var alias2Bean: DummyBean = _beanFactory.getBean("alias2");
      var dummy: DummyBean = _beanFactory.getBean(bean.name);

      assertEquals("pre-defined alias is different to the singleton instance", dummy, alias1Bean);
      assertEquals("post-defined alias is different to the singleton instance", dummy, alias2Bean);
    }

    public function testRegisterBeanFactoryAwareBean(): void {
      const expectedType: Class = DummyFactoryAwareBean;

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyFactoryAwareBean);
      bean.name = "factoryAwareBean";

      _beanFactory.registerBeanDefinition(bean);

      this.assertGetSingletonBean(bean, expectedType);
      assertTrue(
        "BeanFactory not injected",
        DummyFactoryAwareBean(_beanFactory.getBean(bean.name))
          .verifyBeanFactory(_beanFactory)
      );
    }

    public function testRegisterFactoryBean(): void {
      const expectedType: Class = DummyBean;

      var bean: BeanDefinitionSupport = new BeanDefinitionSupport(DummyBeanFactory);
      bean.scope = BeanDefinitionSupport.SCOPE_SINGLETON;
      bean.name = "dummyFactory";

      _beanFactory.registerBeanDefinition(bean);

      this.assertSingletonDefinition(bean);
      assertTrue(
        "BeanDefinitionSupport is not " + bean.type,
        _beanFactory.getBean(bean.name) is expectedType
      );

      //This is just because the factory bean creates new instances every time.
      //But the factory bean is a singleton indeed.
      this.assertPrototypeBean(bean);
    }

    private function assertGetSingletonBean(bean: BeanDefinition, expectedType: Class): void {
      this.assertSingletonDefinition(bean);
      this.assertSingletonBean(bean);
      assertTrue("BeanDefinitionSupport is not " + bean.type, _beanFactory.getBean(bean.name) is expectedType);
    }

    private function assertSingletonDefinition(bean: BeanDefinition): void {
      assertTrue("Factory does not contains bean: " + bean.name, _beanFactory.containsBean(bean.name));
      assertTrue("Definition is not singleton", _beanFactory.isSingleton(bean.name));
      assertTrue("Definition does not matches type " + bean.type, _beanFactory.isTypeMatch(bean.name, bean.type));
      assertFalse("Definition is prototype", _beanFactory.isPrototype(bean.name));
      assertNotNull("BeanDefinitionSupport is null", _beanFactory.getBean(bean.name));
      assertNotUndefined("BeanDefinitionSupport is undefined", _beanFactory.getBean(bean.name));
    }

    private function assertSingletonBean(bean: BeanDefinition): void {
      assertEquals("Equals failed. Not a singleton??", _beanFactory.getBean(bean.name), _beanFactory.getBean(bean.name));
      assertStrictlyEquals("Strict Equals failed. Not a singleton??", _beanFactory.getBean(bean.name), _beanFactory.getBean(bean.name));
    }

    private function assertGetPrototypeBean(bean: BeanDefinition, expectedType: Class): void {
      this.assertPrototypeDefinition(bean);
      this.assertPrototypeBean(bean);
      assertTrue("BeanDefinitionSupport is not " + bean.type, _beanFactory.getBean(bean.name) is expectedType);
    }

    private function assertPrototypeDefinition(bean: BeanDefinition): void {
      assertTrue("Factory does not contains bean: " + bean.name, _beanFactory.containsBean(bean.name));
      assertFalse("Definition is singleton", _beanFactory.isSingleton(bean.name));
      assertTrue("Definition does not matches type " + bean.type, _beanFactory.isTypeMatch(bean.name, bean.type));
      assertTrue("Definition is not prototype", _beanFactory.isPrototype(bean.name));
      assertNotNull("BeanDefinitionSupport is null", _beanFactory.getBean(bean.name));
      assertNotUndefined("BeanDefinitionSupport is undefined", _beanFactory.getBean(bean.name));
    }

    private function assertPrototypeBean(bean: BeanDefinition): void {
      assertFalse("Equals failed. Singleton??", _beanFactory.getBean(bean.name) == _beanFactory.getBean(bean.name));
      assertFalse("Strict Equals failed. Singleton??", _beanFactory.getBean(bean.name) === _beanFactory.getBean(bean.name));
    }

    private function assertPropertyDependency(propertyDummy: DummyBean, dummyBean: DummyBean): void {
      assertNotNull("Property bean is null", propertyDummy);
      assertNotUndefined("Property bean is undefined", propertyDummy)
      assertEquals("Property injected bean is invalid in bean ", propertyDummy, dummyBean.propertyBean);
      assertStrictlyEquals("Property injected bean is invalid", propertyDummy, dummyBean.propertyBean);
    }

    private function assertConstructorDependency(constructorDummy: DummyBean, dummyBean: DummyBean): void {
      assertNotNull("Constructor bean is null", constructorDummy);
      assertNotUndefined("Constructor bean is undefined", constructorDummy)
      assertEquals("Constructor injected bean is invalid", constructorDummy, dummyBean.constructorBean);
      assertStrictlyEquals("Constructor injected bean is invalid", constructorDummy, dummyBean.constructorBean);
    }
  }
}

/********** INTERNAL DEFINITIONS. Mock classes *********/
import com.aconcagua.beans.BeanDefinitionSupport;
import com.aconcagua.factory.BeanFactory;
import com.aconcagua.factory.BeanFactoryAware;

internal class MockBean extends BeanDefinitionSupport {
  private var _registered: Boolean = false;
  private var _instantiated: Boolean = false;

  public function MockBean(type: Class) {
    super(type);
  }

  override public function createInstance(factory:BeanFactory):Object {
    var instance: Object = super.createInstance(factory);
    _instantiated = true;
    return instance;
  }

  public function get isRegistered(): Boolean {
    return _registered;
  }

  public function get isInstantiated(): Boolean {
    return _instantiated;
  }
}
